#pragma once

#include <hash_set>
#include <hash_map>

typedef std::map<std::wstring, sModule*>	MAP_Module_ByName;
typedef std::map<WORD,sServerFaculty*> MAP_ServerFaculty;
typedef std::map<BYTE,sCommonServerStatus*> MAP_CommonServerStatus;
typedef std::map<WORD,sShardStatus*>		MAP_ShardStatus;
typedef std::map<DWORD,sMachineStatus*>		MAP_MachineStatus;
typedef std::map<BYTE,sContent*>			MAP_Content;
typedef std::map<WORD,sShard*>				MAP_Shard;
typedef std::map<DWORD,tagChannel*>			MAP_Channel;
typedef std::map<DWORD,sGameServer*>		MAP_GameServer;


class CShardChannelMgr
{
public:
	CShardChannelMgr();
	~CShardChannelMgr();

public:
	void			SetCurrentSelectShard( WORD wShardID ) { m_wCurrentSelectShardID = wShardID; }
	WORD			GetCurrentSelectShard() const { return m_wCurrentSelectShardID; }
	void			CleanUp();
	tagChannel*		FindChannel( DWORD dwChannelID );
	bool			InsertChannel( DWORD dwChannelID, tagChannel* pChannel );
	MAP_Channel*	GetMapChannel() { return &m_Map_Channel; }
	bool			IsEmpty() const { return m_Map_Channel.empty(); }

private:
	WORD				m_wCurrentSelectShardID;
	MAP_Channel			m_Map_Channel;
};

class CPublisherMgr
{
public:
	CPublisherMgr();
	~CPublisherMgr();

public:
	void			CleanUp();
	tagPublisher*	FindPublisher( DWORD dwPublisherID );
	bool			InsertPublisher( DWORD dwPublisherID, tagPublisher* pPublisher );
	MAP_Publisher*	GetMapPublisher() { return &m_Map_Publisher; }
	bool			IsEmpty() const { return m_Map_Publisher.empty(); }
	int				GetSize() { return m_Map_Publisher.size(); }
	int				GetConnectUserCount(int nPublisherID) { return FindPublisher( nPublisherID )->m_nUserCount; }
	int				GetDailyVisit(int nPublisherID) { return FindPublisher( nPublisherID )->m_dwVisitUserSetDaily; }
	int				GetTotalVisit(int nPublisherID) { return FindPublisher( nPublisherID )->m_dwVisitUserSetTotal; }
	char*			GetName(int nPublisherID) { return FindPublisher( nPublisherID )->m_szName; }


private:
	MAP_Publisher			m_Map_Publisher;
};


class CServerArchitecture : public ISMServerArchitecture
{
public:
	CServerArchitecture();

	bool BuildServerArchitecture(CMsg* pMsg);
	bool BuildSecurityData(CMsg* pMsg);
	void Release();
	void ReleaseSecurityData();

	virtual sModule*		FindModule(DWORD nModuleID);
	virtual sModule*		FindModule(LPCWSTR szModuleName);

	virtual sServerMachine*		 FindServerMachine(DWORD id);
	virtual sServerBody*		 FindServerBody(WORD id);
	virtual sServerFaculty*		 FindServerFaculty(WORD id);
	virtual sServerCord*		 FindServerCord(DWORD id);
	virtual sCommonServerStatus* FindCommonServerStatus(BYTE btDivisionID);
	virtual sShardStatus*		 FindShardStatus(WORD id);
	virtual sMachineStatus*		 FindMachineStatus(DWORD id);
	virtual sShard*				 FindShard(WORD id);
	virtual sContent*			 FindContent(BYTE id);
	virtual sGameServer*		 FindGameServer(DWORD id);

	virtual void QueryAssociatedServerCord(WORD id,LIST_ServerCord& cord_list);

	virtual LIST_Module*		GetModuleList()			{return &m_List_Module ;}
	virtual LIST_Content*		GetContentList()		{return &m_List_Content ;}
	virtual LIST_Division*		GetDivisionList()		{return &m_List_Division ;}
	virtual LIST_Farm*			GetFarmList()			{return &m_List_Farm ;}
	virtual LIST_FarmContent*	GetFarmContentList()	{return &m_List_FarmContent ;}
	virtual LIST_Shard*			GetShardList()			{return &m_List_Shard ;}
	virtual LIST_ServerMachine*	GetServerMachineList()	{return &m_List_ServerMachine ;}
	virtual LIST_ServerBody*	GetServerBodyList()		{return &m_List_ServerBody ;}
	virtual LIST_ServerCord*	GetServerCordList()		{return &m_List_ServerCord ;}

	virtual LIST_SecurityDescription*				GetSecurityDescriptionList(){ return &m_List_SecurityDescription;}
	virtual LIST_SecurityDescriptionGroup*			GetSecurityDescriptionGroupList(){ return &m_List_SecurityDescriptionGroup;}
	virtual LIST_SecurityDescriptionGroupAssign*	GetSecurityDescriptionGroupAssignList(){ return &m_List_SecurityDescriptionGroupAssign;}

	virtual void RefreshAllStatus();
	virtual void RefreshCommonServerStatus();
	virtual void RefreshShardStatus();
	
	virtual void AnalyzeAssociatedServerCord(sServerBody* pServerBody,int& total_count,int& online_count,int& offline_count);

	virtual bool FindSecurityDescription(LPCTSTR szName);
	virtual bool FindSecurityDescription(BYTE nGroupID,DWORD dwSecurityDescriptionID);
	virtual sSecurityDescriptionGroup* FindSecurityDescriptionGroup(DWORD ID);

	virtual sDivision*			GetCurrentDivision(){ return m_pCurrentDivision;}
	virtual LIST_Content*		GetCurrentContentList(){ return &m_CurrentContentList;}

	virtual BYTE	GetShardServiceType(WORD nShardID);
	virtual void	SetShardServiceType(WORD nShardID,BYTE nType);

//
public:
	void OnFRAMEWORKMSG_NOTIFY(CMsg* pMsg);
	void OnSMMSG_USER_STATISTICS_ACK(CMsg* pMsg); 
	void OnSMC_USER_STATISTICS_CHANNEL_INFO_ACK( CMsg* pMsg );
	void OnSMMSG_STATISTICS_PUBLISHER_INFO_ACK( CMsg* pMsg );
	void OnSMMSG_SERVICE_COMPANY_INFO_ACK( CMsg* pMsg );
	void OnSMMSG_STATISTICS_DETAIL_INFO_ACK( CMsg* pMsg );
	void OnSMC_STATISTICS_GAMESERVER_ACK( CMsg* pMsg );

	DWORD	FindSecurityDescriptionByName(LPCTSTR szName);

	void	SetCurrentDivision(BYTE btDivisionID);

	// Channel
	virtual bool			IsUpdateShardChannelData() const;
	virtual tagChannel*		FindChannel( DWORD dwChannelID ) { return m_ShardChannelMgr.FindChannel( dwChannelID ); }
	virtual void			RefreshShardChannel() { m_ShardChannelMgr.CleanUp(); }
	virtual MAP_Channel*	GetMapChannel() { return m_ShardChannelMgr.GetMapChannel(); }
	virtual MAP_Publisher*	GetMapPublisher(){ return m_PublisherMgr->GetMapPublisher(); }
	virtual MAP_Publisher*	GetMapInitPublisher(){ return m_pInitPublisherMgr->GetMapPublisher(); }
	virtual MAP_Publisher*	SetGetMapPublisher();
	virtual tagPublisher*	FindPublisher( DWORD dwChannelID ) { return m_PublisherMgr->FindPublisher( dwChannelID ); }
	virtual bool			HavePublisher() { return m_HavePublisher; }
	virtual int				GetTotalUserCount() { return m_nTotalUserCount; }


protected:
	LIST_Module			m_List_Module;
	LIST_Content		m_List_Content;
	LIST_Division		m_List_Division;
	LIST_Farm			m_List_Farm;
	LIST_FarmContent	m_List_FarmContent;
	LIST_Shard			m_List_Shard;
	LIST_ServerMachine	m_List_ServerMachine;
	LIST_ServerBody		m_List_ServerBody;
	LIST_ServerCord		m_List_ServerCord;

	LIST_SecurityDescription				m_List_SecurityDescription;
	LIST_SecurityDescriptionGroup			m_List_SecurityDescriptionGroup;
	LIST_SecurityDescriptionGroupAssign		m_List_SecurityDescriptionGroupAssign;

	MAP_Module				m_Map_Module;
	MAP_Module_ByName		m_Map_Module_ByName;
	MAP_ServerMachine		m_Map_ServerMachine;
	MAP_ServerBody_ID		m_Map_ServerBody_ID;
	MAP_ServerCord			m_Map_ServerCord;
	MAP_ServerFaculty		m_Map_ServerFaculty;
	MAP_CommonServerStatus	m_Map_CommonServerStatus;
	MAP_ShardStatus			m_Map_ShardStatus;
	MAP_MachineStatus		m_Map_MachineStatus;
	MAP_Content				m_Map_Content;
	MAP_Shard				m_Map_Shard;
	MAP_GameServer			m_Map_GameServer;
	
	typedef stdext::hash_set<DWORD>							SET_SecurityDescription;
	typedef stdext::hash_map<BYTE,SET_SecurityDescription*>	MAP_SecurityDescriptionListByGroupID;
	typedef stdext::hash_map<DWORD,sSecurityDescriptionGroup*> MAP_SecurityDescriptionGroup;

	SET_SecurityDescription					m_Set_SecurityDescription;
	MAP_SecurityDescriptionListByGroupID	m_Map_SecurityDescriptionListByGroupID;
	MAP_SecurityDescriptionGroup			m_Map_SecurityDescriptionGroup;

	sDivision*				m_pCurrentDivision;
	LIST_Content			m_CurrentContentList;
	BYTE					m_btCurrentDivisionID;

	typedef std::map<WORD,BYTE>			MAP_ShardServiceType;
	MAP_ShardServiceType				m_Map_ShardServiceType;

	CShardChannelMgr					m_ShardChannelMgr;
	CPublisherMgr*						m_PublisherMgr;

	MAP_ShardList						m_Map_ShardList;

	CPublisherMgr*						m_pInitPublisherMgr;



	bool								m_HavePublisher;
	int									m_nTotalUserCount;
};

extern CServerArchitecture g_ServerArchitecture;